package com.zyq.intercepter;

import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.ObjectUtils;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author xiaochi
 * @date 2021/4/30 18:02
 * @desc AbstractBaseInterceptor
 */
public abstract class AbstractBaseInterceptor implements BaseInterceptor{

    /**
     * 执行
     * @param request
     * @param response
     * @param method
     * @return
     */
    public boolean doHandler(HttpServletRequest request, HttpServletResponse response, HandlerMethod method){
        return this.execute(request,response,method);
    }

    /**
     * 具体实现
     * @param request
     * @param response
     * @param method
     * @return
     */
    protected abstract boolean execute(HttpServletRequest request, HttpServletResponse response, HandlerMethod method);

    /**
     * 获取参数(注意：获取不到json参数，只能获取表单参数)
     * @param request
     * @return
     */
    public String getParameter(HttpServletRequest request){
        StringBuilder sb = new StringBuilder(100);
        Enumeration<String> parameteres = request.getParameterNames();
        if (parameteres.hasMoreElements()){
            while (parameteres.hasMoreElements()){
                String key = parameteres.nextElement();
                String[] values = request.getParameterValues(key);
                sb.append(key).append("=");
                for (String val : values){
                    sb.append(val);
                }
                sb.append(",");
            }
        }
        return sb.toString().length() > 0 ? sb.toString().substring(0,sb.length()-1) : "";
    }

    /**
     * 解析spring EL表达式
     * @param key    key
     * @param method method
     * @param args   args
     * @return parse result
     */
    private ExpressionParser parser = new SpelExpressionParser();
    private LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
    public String parse(String key, Method method, Object[] args) {
        String[] params = discoverer.getParameterNames(method);
        if (null == params || params.length == 0 || !key.contains("#")) {
            return key;
        }
        EvaluationContext context = new StandardEvaluationContext();
        for (int i = 0; i < params.length; i++) {
            if (null != args[i]){
                context.setVariable(params[i], args[i]);
            }else {
                context.setVariable(params[i],"");
            }
        }
        return parser.parseExpression(key).getValue(context, String.class);
    }

    /**
     * 获取spring EL表达式的key
     * @return
     */
    public String getSpelKey(String spelKey){
        if (null == spelKey || spelKey.length() == 0 || !spelKey.contains("#")) {
            return null;
        }
        return spelKey.replaceAll("#\\{","").replaceAll("}","");
    }

    /**
     * 获取spring EL表达式的key的值
     * @return
     */
    public String getSpelValueByKey(String spelKey,HttpServletRequest request){
        String parameter = this.getParameter(request);
        if (!ObjectUtils.isEmpty(parameter)){
            Map<String, String> parameterMap = Arrays.stream(parameter.split(",")).map(s -> s.split("=")).collect(Collectors.toMap(item -> item[0], item -> item[1]));
            if (!ObjectUtils.isEmpty(parameterMap)){
                return parameterMap.get(getSpelKey(spelKey));
            }
        }
        return null;
    }
}